#include "IntegerFormatter.h"
#include <sstream>

IntegerFormatter::IntegerFormatter(void)
{
    _base = 10;
    _width = 0;
    _padding = ' ';
    _adjustment = std::ios_base::right;
    _caseInsensitive = true;
    _showBase = false;
    _upperCase = true;
}

IntegerFormatter::~IntegerFormatter(void)
{
}

IntegerFormatter & IntegerFormatter::setBase(int base)
{
    if(base < 2 || base > 36)
    {
        throw std::runtime_error("");
    }
    _base = base;
    return *this;
}

IntegerFormatter & IntegerFormatter::setWidth(int width)
{
    _width = width;
    return *this;
}

IntegerFormatter & IntegerFormatter::setPadding(char padding)
{
    _padding = padding;
    return *this;
}

IntegerFormatter & IntegerFormatter::setUpperCase(bool upper)
{
    _caseInsensitive = false;
    _upperCase = upper;
    return *this;
}

IntegerFormatter & IntegerFormatter::setLowerCase(bool lower)
{
    return setUpperCase(!lower);
}

OutFormatter IntegerFormatter::out(int value) const
{
    return OutFormatter(*this,value);
}

IntegerFormatter & IntegerFormatter::setShowBase(bool show)
{
    _showBase = show;
    return *this;
}

IntegerFormatter & IntegerFormatter::setNoShowBase(bool noShow)
{
    return setShowBase(!noShow);
}

IntegerFormatter & IntegerFormatter::setIgnoreCase(bool ignore)
{
    _caseInsensitive = ignore;
    return *this;
}

IntegerFormatter & IntegerFormatter::setAdjust(std::ios_base::fmtflags flag)
{
    _adjustment = (_adjustment & ~std::ios_base::adjustfield) | flag;
    return *this;
}

IntegerFormatter & IntegerFormatter::adjustLeft()
{
    setAdjust(std::ios_base::left);
    return *this;
}

IntegerFormatter & IntegerFormatter::adjustRight()
{
    setAdjust(std::ios_base::right);
    return *this;
}

IntegerFormatter & IntegerFormatter::adjustInternal()
{
    setAdjust(std::ios_base::internal);
    return *this;
}

InFormatter IntegerFormatter::in(int & value) const
{
    return InFormatter(*this, value);
}

char IntegerFormatter::digitValue(int digit) const
{
	if (digit >= _base)
	{
		throw std::runtime_error("Unknown digit");
	}
	if(digit >= 0 && digit <= 9)
	{
		return digit + '0';
	}
	else 
	{
		return digit - 10 + (_upperCase ? 'A' : 'a');
	}
}

int IntegerFormatter::valueDigit(char digit) const
{
    int res = _base;
	if(digit >= '0' && digit <= '9')
	{
		res = digit - '0';
	}
	else if((_upperCase || _caseInsensitive) && (digit >='A' && digit <='A' + _base - 10))
	{
		res = digit + 10 - 'A';
	}
	else if((!_upperCase || _caseInsensitive) && (digit >='a' && digit <='a' + _base - 10))
	{
		res = digit + 10 - 'a';
	}
    if (res >= _base)
	{
		throw std::runtime_error("Unknown digit");
	}
    return res;
}